﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Web;
using System.Globalization;
using System.Data;
using System.Security.AccessControl;

// <summary>
/// Author: 
/// Created Date:10-Feb-2011
/// Description:Used to save the Common variables and functions.
/// </summary>
namespace EncircleFTM
{
    public class clsCommonData
    {
        #region "Gobal Parameters"
        public static string SessionToken = string.Empty;
        public static string APP_PATH = GetAppPath();
        public static string APP_DATA_PATH = GetAppDataPath();
        #endregion

        #region "Common String"
        public const string STR_APPNAME = "ECHO";
        public const string STR_FOLDER_LOG_FAILED = "Log";
        public const string STR_FOLDER_LOG_SUCCESS = "Log";
        public const string STR_CONFIG_XML = "Config.xml";
        public const string STR_ADDITIONAL_XML = "AdditonalInfo.xml";
        public const string STR_STATICLIST_XML = "StaticList.xml";
        public const string STR_ERROR_TXT = "Log\\ErrorLog.txt";
        public const string STR_LOG_FILE = "Log\\Log.xml";
        public const string STR_ERROR = "Error:";
        public const string STR_FAILED = "FAILED";
        public const string STR_SUCCESS = "SUCCESS";
        public const string STR_INPROGRESS = "InProgress";
        public const string STR_SCHEDULER_APP = "Scheduler.exe";
        public const string STR_SCHEDULER_APP_NAME = "Scheduler";
        public const string STR_STATIC_PROVIDER = "Provider";
        public const string STR_STATIC_PROCEDURE1 = "Procedure1";
        public const string STR_STATIC_PROCEDURE2 = "Procedure2";
        public const string STR_STATIC_NOTE1 = "Note1";
        public const string STR_STATIC_NOTE2 = "Note2";
        #endregion

        #region "Messages"
        public const string MSG_FAILURE = "Config file does not exist!";
        public const string MSG_REENTER_SETTINGS = "Please re-enter the settings details.";
        public const string MSG_SUCCESS = "Successfully Updated";
        public const string MSG_UPDATE_FAILURE = "Unable to Update Config";
        public const string MSG_ENCIRCLE = "Encircle";
        public const string MSG_ERRORLOG = "No Error data found";
        public const string MSG_CONFIRM = "Are you sure you want to clear the Log";
        public const string MSG_UNABLE_TO_ADDPRINTER = "Unable to add printer option.";
        public const string MSG_UNABLE_TO_PROCEED = "Unable to proceed the insllation without settings.";
        public const string MSG_CONTINUE_INSTALL = "Continuing Installation.";
        #endregion

        #region "Common enumerations"
        /// <summary>
        /// Used to handle clear log schedule.
        /// </summary>
        public enum ClearLogSchedule
        {
            None = 0,
            EveryDay = 1,
            EveryWeek = 2,
            EveryMonth = 3,
            EveryQuarter = 4,
            EveryHalfyear = 5,
            EveryYear
        }
        #endregion

        #region "Common Functions"

        /// <summary>
        /// To get the Application Path.
        /// </summary>
        /// <returns></returns>
        public static string GetAppPath()
        {
            string path = string.Empty;
            try
            {
                path = System.IO.Path.GetDirectoryName(
      System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);

                if (path.ToUpper().StartsWith("FILE:\\"))
                    path = path.Trim().ToUpper().Replace("FILE:\\", "");

                return path;
            }
            catch (Exception ex)
            {
                clsCommonData.WriteError(ex.ToString());
            }
            return path;
        }

        /// <summary>
        /// To get the Current User's ApplicationData folder Path.
        /// </summary>
        /// <returns></returns>
        public static string GetAppDataPath()
        {
            string path = string.Empty;
            try
            {
                var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
             //   path = appDataPath.Substring(0, appDataPath.LastIndexOf(@"\")) + @"\EncircleFTM_Config";
                path = appDataPath + @"\Encircle";
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                if (!Directory.Exists(path + @"\Log"))
                {
                    Directory.CreateDirectory(path + @"\Log");
                    File.Copy(Path.Combine(APP_PATH, STR_LOG_FILE), path + "\\" + STR_LOG_FILE);                    
                    File.Copy(Path.Combine(APP_PATH, STR_ERROR_TXT), path + "\\" + STR_ERROR_TXT);
                }
                else
                {
                    if (!File.Exists(path + "\\" + STR_LOG_FILE))
                        File.Copy(Path.Combine(APP_PATH, STR_LOG_FILE), path + "\\" + STR_LOG_FILE);
                    if (!File.Exists(path + "\\" + STR_ERROR_TXT))
                        File.Copy(Path.Combine(APP_PATH, STR_ERROR_TXT), path + "\\" + STR_ERROR_TXT);
                }                
            }
            catch (Exception ex) { clsCommonData.WriteError(ex.ToString()); }
            return path;
        }
        /// <summary>
        /// To Diplay the Text File While Error Occurs.
        /// </summary>
        /// <param name="errorMessage"></param>
        public static void WriteError(string errorMessage)
        {
            try
            {
                var ErrorFilePath = System.IO.Path.Combine(APP_DATA_PATH, STR_ERROR_TXT);
                FileInfo fInfo = new FileInfo(ErrorFilePath);

                if (!Directory.Exists(fInfo.DirectoryName))
                    Directory.CreateDirectory(fInfo.DirectoryName);

                if (!File.Exists(ErrorFilePath))
                    File.Create(ErrorFilePath);

                StreamWriter FileWriter = new StreamWriter(ErrorFilePath, true);
                System.Text.StringBuilder sb = new StringBuilder();
                sb.Append("--------------------------------------------------------------");
                sb.Append("\r\nLog Entry : " + DateTime.Now.ToString(CultureInfo.InvariantCulture));
                sb.Append(System.Environment.NewLine);
                sb.Append("Error Message:" + errorMessage);
                sb.Append(System.Environment.NewLine);
                sb.Append("--------------------------------------------------------------");
                FileWriter.Write(sb.ToString());
                sb = null;
                FileWriter.Flush();
                FileWriter.Close();
                FileWriter = null;

            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.Message, clsCommonData.STR_APPNAME);
            }
        }

        /// <summary>
        /// To read the Text File While Error Occurs. 
        /// </summary>
        /// <returns></returns>
        public static string ReadLog()
        {
            string Content = string.Empty;
            try
            {

                if (File.Exists(System.IO.Path.Combine(APP_DATA_PATH, STR_ERROR_TXT)))
                {
                    StreamReader FileReader = new StreamReader(System.IO.Path.Combine(APP_DATA_PATH, STR_ERROR_TXT));
                    Content = FileReader.ReadToEnd();
                    FileReader.Close();
                    FileReader = null;
                    return Content;
                }
            }
            catch (Exception ex)
            {
                clsCommonData.WriteError(ex.ToString());
            }
            return Content;
        }

        /// <summary>
        /// To clear the Error File.
        /// </summary>
        public static void ClearLog()
        {
            try
            {
                if (File.Exists(System.IO.Path.Combine(APP_DATA_PATH, STR_ERROR_TXT)))
                {
                    File.WriteAllText(System.IO.Path.Combine(APP_DATA_PATH, STR_ERROR_TXT), String.Empty);
                }
                else
                {
                    throw new FileNotFoundException();
                }
            }
            catch (Exception ex)
            {
                //WriteError(ex.Message);
            }
        }

        /// <summary>
        /// To read file transfer log details from log.xml file 
        /// </summary>
        /// <returns></returns>
        public static clsLog ReadLogData()
        {
            clsLog objLog = new clsLog();
            try
            {
                // Read XML DAta or Deserialize xml data with Entity class
                System.Xml.Serialization.XmlSerializer s = new System.Xml.Serialization.XmlSerializer(typeof(clsLog));
                if (File.Exists(System.IO.Path.Combine(APP_DATA_PATH, STR_LOG_FILE)))
                {
                    System.IO.FileStream myFileStream = new System.IO.FileStream(System.IO.Path.Combine(APP_DATA_PATH, STR_LOG_FILE), System.IO.FileMode.Open);
                    objLog = (clsLog)s.Deserialize(myFileStream);
                    myFileStream.Close();
                    myFileStream = null;
                }
                s = null;
                return objLog;
            }
            catch (Exception ex)
            {
                WriteError(ex.Message);
            }
            return objLog;
        }

        /// <summary>
        /// To append file transfer log information
        /// </summary>
        /// <param name="pObjLogData"></param>
        /// <returns></returns>
        public static Boolean writeLogData(LogData pObjLogData, int updateIndex)
        {
            clsLog objLog = new clsLog();
            string strLogFilePath = System.IO.Path.Combine(APP_DATA_PATH, STR_LOG_FILE);
            FileInfo fInfo = new FileInfo(strLogFilePath);

            if (!Directory.Exists(fInfo.DirectoryName))
                Directory.CreateDirectory(fInfo.DirectoryName);
            try
            {
                if (pObjLogData == null) return false;

                if (File.Exists(strLogFilePath))
                {
                    //Again Serialize the data
                    System.Xml.Serialization.XmlSerializer objXMLSerialization = new System.Xml.Serialization.XmlSerializer(typeof(clsLog));
                    System.IO.FileStream myFileStream = new System.IO.FileStream(strLogFilePath, System.IO.FileMode.Open);
                    objLog = (clsLog)objXMLSerialization.Deserialize(myFileStream);
                    myFileStream.Close();
                    myFileStream = null;
                    objXMLSerialization = null;
                }

                //Adding the Logdata to the log list.
                if (updateIndex > -1)
                {
                    if (objLog != null && objLog.lstLogData != null)
                    {
                        if (objLog.lstLogData.Count > updateIndex)
                        {
                            objLog.lstLogData[updateIndex].FileName = pObjLogData.FileName;
                            objLog.lstLogData[updateIndex].Status = pObjLogData.Status;
                            objLog.lstLogData[updateIndex].Remark = pObjLogData.Remark;

                        }
                    }
                }
                else
                {
                    objLog.lstLogData.Add(pObjLogData);
                }

                //Check file exists and delete 
                if (File.Exists(strLogFilePath)) File.Delete(strLogFilePath);

                //Write the data to the XML file using Serialization
                System.Xml.Serialization.XmlSerializer s = new System.Xml.Serialization.XmlSerializer(typeof(clsLog));
                System.IO.StreamWriter writer = new System.IO.StreamWriter(strLogFilePath);
                s.Serialize(writer, objLog);
                writer.Close();
                writer = null;
                s = null;
                return true;
            }
            catch (Exception ex)
            {
                WriteError(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// Used to handle scheduler validation status
        /// </summary>
        public class SchedulerStatus
        {
            public double ElapsedInterval = 10080000;
            public bool isReached = false;
        }

        /// <summary>
        /// To clear the ErrorLog File based on the Last Updated Date.
        /// </summary>
        /// <param name="pSchedule"></param>
        /// <param name="pLastDt"></param>
        public static SchedulerStatus SchedulerClearLog(clsCommonData.ClearLogSchedule pSchedule, int Day, int Month, int Year, int Hour, int Min, int sec)
        {
            SchedulerStatus objStatus = new SchedulerStatus();
            DateTime TodaysDt = System.DateTime.Now;
            if (Year <= 0) Year = DateTime.Now.Year;
            if (Month <= 0) Month = 1;
            if (Day <= 0) Day = 1;
            if (Hour <= 0) Hour = 00;
            if (Min <= 0) Min = 00;
            if (sec <= 0) sec = 00;

            DateTime pLastDt = new DateTime(Year, Month, Day, Hour, Min, sec);
            int NoOfDays = 0;
            double Duration = 0;
            int NoOfMonth = 0;
            Boolean status = false;
            TimeSpan span;
            double noOfHrs = 0;
            try
            {

                switch (pSchedule)
                {
                    case clsCommonData.ClearLogSchedule.EveryDay:
                        noOfHrs = 24; //1 day is converted to hours (1 * 24)
                        span = TodaysDt.Subtract(pLastDt);
                        Duration = span.TotalHours;
                        if (Duration >= noOfHrs)
                        {
                            objStatus.isReached = true;
                            objStatus.ElapsedInterval = Convert.ToInt64(ConverthoursToMilliseconds(noOfHrs));
                        }
                        else
                        {
                            objStatus.isReached = false;
                            objStatus.ElapsedInterval = Convert.ToInt64(ConverthoursToMilliseconds(noOfHrs - Duration));
                        }
                        break;

                    case clsCommonData.ClearLogSchedule.EveryWeek:
                        noOfHrs = 168; //1 week to converted to hours (7 * 24)
                        span = TodaysDt.Subtract(pLastDt);
                        Duration = span.TotalHours;
                        if (Duration >= noOfHrs)
                        {
                            objStatus.isReached = true;
                            objStatus.ElapsedInterval = Convert.ToDouble(ConverthoursToMilliseconds(noOfHrs));
                        }
                        else
                        {
                            objStatus.isReached = false;
                            objStatus.ElapsedInterval = Convert.ToDouble(ConverthoursToMilliseconds(noOfHrs - Duration));
                        }
                        break;

                    case clsCommonData.ClearLogSchedule.EveryMonth:
                        noOfHrs = 720; //1 Month is converted to hours (30 * 24)
                        span = TodaysDt.Subtract(pLastDt);
                        Duration = span.TotalHours;
                        if (Duration >= noOfHrs)
                        {
                            objStatus.isReached = true;
                            objStatus.ElapsedInterval = Convert.ToDouble(ConverthoursToMilliseconds(noOfHrs));
                        }
                        else
                        {
                            objStatus.isReached = false;
                            objStatus.ElapsedInterval = Convert.ToDouble(ConverthoursToMilliseconds(noOfHrs - Duration));
                        }
                        break;
                    case clsCommonData.ClearLogSchedule.EveryQuarter:
                        noOfHrs = 2160; //3 Months are converted to hours (720 * 3)
                        span = TodaysDt.Subtract(pLastDt);
                        Duration = span.TotalHours;
                        if (Duration >= noOfHrs)
                        {
                            objStatus.isReached = true;
                            objStatus.ElapsedInterval = Convert.ToDouble(ConverthoursToMilliseconds(noOfHrs));
                        }
                        else
                        {
                            objStatus.isReached = false;
                            objStatus.ElapsedInterval = Convert.ToDouble(ConverthoursToMilliseconds(noOfHrs - Duration));
                        }
                        break;
                    case clsCommonData.ClearLogSchedule.EveryHalfyear:
                        noOfHrs = 4320; //6 Months are converted to hours (720 * 6)
                        span = TodaysDt.Subtract(pLastDt);
                        Duration = span.TotalHours;
                        if (Duration >= noOfHrs)
                        {
                            objStatus.isReached = true;
                            objStatus.ElapsedInterval = Convert.ToDouble(ConverthoursToMilliseconds(noOfHrs));
                        }
                        else
                        {
                            objStatus.isReached = false;
                            objStatus.ElapsedInterval = Convert.ToDouble(ConverthoursToMilliseconds(noOfHrs - Duration));
                        }
                        break;
                    case clsCommonData.ClearLogSchedule.EveryYear:
                        noOfHrs = 8640; //6 Months are converted to hours (720 * 12)
                        span = TodaysDt.Subtract(pLastDt);
                        Duration = span.TotalHours;
                        if (Duration >= noOfHrs)
                        {
                            objStatus.isReached = true;
                            objStatus.ElapsedInterval = Convert.ToDouble(ConverthoursToMilliseconds(noOfHrs));
                        }
                        else
                        {
                            objStatus.isReached = false;
                            objStatus.ElapsedInterval = Convert.ToDouble(ConverthoursToMilliseconds(noOfHrs - Duration));
                        }
                        break;
                    case ClearLogSchedule.None:
                        objStatus.isReached = false;
                        objStatus.ElapsedInterval = 1;
                        break;
                }
            }
            catch (Exception ex)
            {
                WriteError(ex.ToString());
                status = false;
            }
            return objStatus;
        }

        /// <summary>
        /// Used to convert days to milliseconds 
        /// </summary>
        /// <param name="days"></param>
        /// <returns></returns>
        public static double ConvertdaysToMilliseconds(double days)
        {
            return TimeSpan.FromDays(days).TotalMilliseconds;
        }

        /// <summary>
        /// Used to convert hours to milliseconds 
        /// </summary>
        /// <param name="hours"></param>
        /// <returns></returns>
        public static double ConverthoursToMilliseconds(double hours)
        {
            return TimeSpan.FromHours(hours).TotalMilliseconds;
        }

        /// <summary>
        /// Used to start clear log scheduler
        /// </summary>
        public static void StartScheduler()
        {
            try
            {
                System.Diagnostics.ProcessStartInfo process = new System.Diagnostics.ProcessStartInfo(System.IO.Path.Combine(clsCommonData.APP_PATH, STR_SCHEDULER_APP), "START");
                process.CreateNoWindow = true;
                process.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                process.UseShellExecute = false;
                process.RedirectStandardOutput = true;
                System.Diagnostics.Process.Start(process);
            }
            catch (Exception ex) { }
       
        }

        /// <summary>
        /// Used to stop clear log scheduler
        /// </summary>
        public static void StopScheduler()
        {
            System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName(STR_SCHEDULER_APP_NAME);
            if (process != null && process.Length > 0)
                process[0].Kill();
        }

        /// <summary>
        /// Check Application Folder Access Rights
        /// </summary>
        /// <param name="FolderPath"></param>
        /// <returns></returns>
        public static bool CheckFolderAccessRights(string FolderPath, string User, ref string Message)
        {
            bool isValidRights = false;
            bool isUserExists = false;

            try
            {
                string strAppPath = FolderPath;
                string strUser = User; //string.Format(@"{0}\{1}", System.Environment.UserDomainName, System.Environment.UserName);
                System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(strAppPath);

                if (dirInfo.Exists)
                {
                    System.Security.AccessControl.AuthorizationRuleCollection ruleColl =
                        dirInfo.GetAccessControl().GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
                    foreach (System.Security.AccessControl.FileSystemAccessRule rule in ruleColl)
                    {
                        if (rule.IdentityReference.Value.ToUpper().Contains(User.ToUpper())) // == strUser.ToUpper())
                        {
                            isUserExists = true;

                            //Validate Access Rights
                            System.Security.AccessControl.FileSystemRights rights = rule.FileSystemRights;
                            if (rights == System.Security.AccessControl.FileSystemRights.FullControl &&
                                (rule.AccessControlType == System.Security.AccessControl.AccessControlType.Allow))
                            {
                                isValidRights = true;
                                Message = "User has full access control.";
                                break;
                            }
                            else
                            {
                                Message = string.Format("Application folder '{0}' does not have enough access rights for the user '{1}'\r\n. Please contact administrator.", strAppPath, strUser);
                                isValidRights = false;
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Everyone user Rights validation status:**{0}.\r\n" +
                    "Current User Rights validation Status:**{1}.\r\n", ex.Message, Message), "ECHO");
               
                isValidRights = false;
            }
            if (!isUserExists) Message = "Does not have enough access rights to the application folder.";
            return isValidRights;
        }
        #endregion
    }
}

